﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Media;
using SIPVoipSDK;
using System.IO;
using System.Linq;
using System.Threading;

using BaHuan.BusinessLayer;
using BaHuan.Entities;
using BaHuan.Common;

namespace BaHuan
{
    using ConnectionInfo = KeyValuePair<int, string>;
    using ConnectionsTbl = Dictionary<int, string>;    

    public partial class FrmChoCuocGoi : Form
    {
        public class LineInfo
        {
            public LineInfo(int id)
            {
                m_id = id;
                m_conn = new ConnectionsTbl();
                m_bCalling = false;
                m_bCallEstablished = false;
                m_bCallRecordStarted = false;
            }

            public ConnectionsTbl m_conn;
            public int m_id;
            public bool m_bCalling;
            public bool m_bCallEstablished;
            public bool m_bCallRecordStarted;
        }

        private KhachHangManagement khachhangMgt = new KhachHangManagement();
        private ChiNhanhKhachHangManagement chinhanhkhachhangMgt = new ChiNhanhKhachHangManagement();

        public KhachHang khachhang = new KhachHang();
        public ChiNhanhKhachHang chinhanhkhachhang = new ChiNhanhKhachHang();

        private FrmCuocGoiDen dlg;
        private CAbtoPhone AbtoPhone = new CAbtoPhone();
        private SoundPlayer myPlayer = new System.Media.SoundPlayer();
        private Stream SoundResource;
        private string sSDT = "";
        private int isUnknown = 0;
        public Thread subThread;
        private ArrayList m_lineConnections = new ArrayList();

        private int m_curLineId = 1;
        private int m_MP3RecordingEnabled = 0;
        private int m_AutoAnswerEnabled = 0;

        public NhanVien nhanvien;
        public NhanVien NhanVien
        {
            set { this.nhanvien = value; }
            get { return this.nhanvien; }
        }

        public FrmChoCuocGoi()
        {
            this.AbtoPhone.OnEstablishedCall += new _IAbtoPhoneEvents_OnEstablishedCallEventHandler(this.AbtoPhone_OnEstablishedCall);
            this.AbtoPhone.OnIncomingCall += new _IAbtoPhoneEvents_OnIncomingCallEventHandler(this.AbtoPhone_OnIncomingCall);
            this.AbtoPhone.OnClearedCall += new _IAbtoPhoneEvents_OnClearedCallEventHandler(this.AbtoPhone_OnClearedCall);
            this.AbtoPhone.OnEstablishedConnection += new _IAbtoPhoneEvents_OnEstablishedConnectionEventHandler(this.AbtoPhone_OnEstablishedConnection);
            this.AbtoPhone.OnToneReceived += new _IAbtoPhoneEvents_OnToneReceivedEventHandler(this.AbtoPhone_OnToneReceived);
            this.AbtoPhone.OnClearedConnection += new _IAbtoPhoneEvents_OnClearedConnectionEventHandler(this.AbtoPhone_OnClearedConnection);

            InitializeComponent();
        }

        ///////////////////////////////////
        //Utils

        private LineInfo GetCurLine()
        {
            return (LineInfo)m_lineConnections[m_curLineId - 1];
        }

        private LineInfo GetLine(int lineId)
        {
            return (LineInfo)m_lineConnections[lineId - 1];
        }

        private void FrmChoCuocGoi_Load(object sender, EventArgs e)
        {
            //Make lines
            m_lineConnections.Add(new LineInfo(1));

            //Get config
            CConfig phoneCfg = AbtoPhone.Config;

            phoneCfg.AutoAnswerEnabled = 0;
            phoneCfg.CallerId = "98";
            phoneCfg.DialToneEnabled = 0;
            phoneCfg.LicenseDomain = "";
            phoneCfg.LicenseKey = "0ADB-160B-AF3A-697A-83C6-456C-14E4-263D";
            phoneCfg.LicenseUserId = "Khoi Luong-7734 Donnybrook Ct, #106";
            phoneCfg.ListenPort = 5060;
            phoneCfg.LocalAudioEnabled = 1;
            phoneCfg.ProxyDomain = "";
            phoneCfg.ProxyPass = "";
            phoneCfg.ProxyUser = "";
            phoneCfg.RegAuthId = "98";
            phoneCfg.RegDomain = "172.16.1.19";
            phoneCfg.RegExpire = 300;
            phoneCfg.RegPass = "98";
            phoneCfg.RegRealm = "";
            phoneCfg.RegUser = "98";
            phoneCfg.RtpStartPort = 17384;
            phoneCfg.SamplesPerFrame = 32000;
            phoneCfg.UserAgent = "ABTO SIP SDK";
            phoneCfg.MP3RecordingEnabled = 1;

            //Apply modified config
            AbtoPhone.ApplyConfig();

            try
            {
                AbtoPhone.Initialize();
            }
            catch (Exception)
            {
                return;
            }

            //Get state
            m_MP3RecordingEnabled = phoneCfg.MP3RecordingEnabled;
            m_AutoAnswerEnabled = phoneCfg.AutoAnswerEnabled;
        }

        ///////////////////////////////////
        //Events

        private void AbtoPhone_OnEstablishedCall(string adress, int lineId)
        {
            //Update line state
            LineInfo lnInfo = GetLine(lineId);
            lnInfo.m_bCallEstablished = true;
            lnInfo.m_bCalling = false;

            //Record call
            if (lnInfo.m_bCallRecordStarted)
            {
                AbtoPhone.StopRecording();
            }
            else
            {
                AbtoPhone.StartRecording(@"C:\Users\ZZ\Desktop\test.mp3");
            }
        }

        private void AbtoPhone_OnIncomingCall(string adress, int lineId)
        {
            LineInfo lnInfo = GetCurLine();

            //Sound waiting
            SoundResource = Properties.Resources.disco;
            myPlayer.Stream = SoundResource;
            myPlayer.PlayLooping();

            //Get phone number
            string[] sCallerInfo = adress.Split('"', '<', ':', '@');
            sSDT = sCallerInfo[4];
            
            //Show form
            dlg = new FrmCuocGoiDen();
            dlg.txtSDT.Text = sSDT;

            khachhang = (from p in GetAllKhachHang()
                         where p.DienThoai.Contains(sSDT)
                         select p).FirstOrDefault();

            if (khachhang.Id != 0)
            {
                dlg.rtbNguoiGoi.Text = khachhang.Ten;
            }
            else
            {
                chinhanhkhachhang = (from p in GetAllChiNhanhKhachHang()
                                     where p.DienThoai.Contains(sSDT)
                                     select p).FirstOrDefault();

                if (chinhanhkhachhang.Id != 0)
                {
                    dlg.rtbNguoiGoi.Text = chinhanhkhachhang.Ten;

                    khachhang = (from p in GetAllKhachHang()
                                 where p.Id == chinhanhkhachhang.IdKhachHang
                                 select p).FirstOrDefault();
                }
                else
                {
                    dlg.rtbNguoiGoi.Text = "Chưa biết";
                    isUnknown = 1;
                }
            }

            this.rtbLabel.Text = "\r\n   Đang nhận cuộc gọi";
            
            if (dlg.ShowDialog() == DialogResult.Yes)
            {
                AbtoPhone.AnswerCall();

                subThread = new Thread(CallForm);
                subThread.Start();

                //Stop sound waiting
                myPlayer.Stop();
                lnInfo.m_bCallRecordStarted = !lnInfo.m_bCallRecordStarted;
            }
            else
            {
                AbtoPhone.RejectCall();

                //Stop sound waiting
                myPlayer.Stop();
            }
        }

        private void AbtoPhone_OnClearedCall(string Msg, int status, int lineId)
        {
            //Update line state
            LineInfo lnInfo = GetLine(lineId);
            lnInfo.m_bCallEstablished = false;
            lnInfo.m_bCalling = false;

            //Close form popup
            dlg.Close();

            this.rtbLabel.Text = "\r\n   Đang chờ cuộc gọi";
        }

        private void AbtoPhone_OnToneReceived(int tone, int connectionId, int lineId)
        {
            LineInfo lnInfo = GetLine(lineId);

            StringBuilder sb = new StringBuilder();
            sb.Append((char)tone);
        }

        private void AbtoPhone_OnEstablishedConnection(string addrFrom, string addrTo, int connectionId, int lineId)
        {
            LineInfo lnInfo = GetLine(lineId);
            string addr = lnInfo.m_bCalling ? addrTo : addrFrom;

            lnInfo.m_conn.Add(connectionId, addr);
        }

        private void AbtoPhone_OnClearedConnection(int connectionId, int lineId)
        {
            LineInfo lnInfo = GetLine(lineId);
            lnInfo.m_conn.Remove(connectionId);
        }

        ///////////////////////////////////
        //Sub thread

        public void CallForm()
        {            
            if (isUnknown == 0) //Existed object
            {
                FrmPhieuXuatHang frm = new FrmPhieuXuatHang();
                frm.NhanVien = this.nhanvien;
                frm.parentFrmChoCuocGoi = this;
                frm.ShowDialog();                
            }
            else //Unknown object
            {
                FrmKhachHang frm = new FrmKhachHang();
                frm.parentForm = this;
                frm.ShowDialog();
            }            
        }

        ///////////////////////////////////
        //Get data from db

        public List<ChiNhanhKhachHang> GetAllChiNhanhKhachHang()
        {
            ResultObj resultObj = new ResultObj();

            resultObj = chinhanhkhachhangMgt.GetAllChiNhanhKhachHang();
            List<ChiNhanhKhachHang> listChiNhanhKhachHang = (List<ChiNhanhKhachHang>)resultObj.Result;

            return listChiNhanhKhachHang;
        }

        public List<KhachHang> GetAllKhachHang()
        {
            ResultObj resultObj = new ResultObj();

            resultObj = khachhangMgt.GetAllKhachHang();
            List<KhachHang> listKhachHang = (List<KhachHang>)resultObj.Result;

            return listKhachHang;
        }
    }
}
